package Gradle基础;

/*Gradle构建脚本描述了构建项目的过程。大多数项目都不是独立的。他们需要一些文件来编译和测试源文件。例如，要使用Hibernate，我们必须在类路径中包含一
些Hibernate JAR。 Gradle使用一些独特的脚本来管理依赖项，需要下载它们。

依赖项用于辅助任务，例如项目所需的JAR文件和外部JAR。每个依赖项都应用于指定的范围。例如，依赖项用于编译源代码，其中一些将在运行时可用。 Gradle在配
置的帮助下表示依赖项的范围，并且唯一的名称可以识别每个配置。大多数Gradle插件都支持项目的预定义配置。

Gradle考虑了构建和发布项目的结果。发布基于我们定义的任务。它可以将文件复制到本地目录或将其上传到远程Maven或Lvy存储库。我们可以在同一多项目构建中使
用来自另一个项目的这些文件。发布任务的过程称为发布。

《依赖配置》
依赖关系配置是一组依赖关系和工件。以下是配置的三个主要任务:

1.Declaring dependencies
2.Resolving dependencies
3.Exposing artifacts for consumptions

1.声明依赖(Declaring Dependency)
依赖性是任何项目的重要组成部分。我们必须声明一个依赖项才能使用它。依赖性配置是定义一组依赖性的过程。此功能用于声明外部依赖关系，我们希望从网络上下载这些
依赖关系。

考虑下面的Hibernate-core依赖示例:

apply plugin: 'java.' 
repositories {
   mavenCentral()
}
dependencies {
	compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
		testCompile group: 'junit', name: 'junit', version: '4.+'
}
可以在项目的不同阶段使用依赖项。这些阶段可以是:

Compile       -  在编译时，我们将使用编译项目生产源所需的依赖项。
Runtime       -  生产类在运行时使用这些依赖项。默认情况下，它还包含编译时依赖项。
Test Compile  -  编译项目的测试源需要这些依赖项。它还包含编译后的生产类和编译时依赖项。
Test Runtime  -  运行测试需要这些依赖项。它还包含运行时和测试编译依赖项。

2.解决依赖关系(Resolving Dependencies)
插件使用配置并获取已定义任务的输入。例如，Gradle项目使用Spring Web Framework jar文件，该文件必须从Maven Central下载。

3.Exposing Artifacts for COnsumption
该插件使用用于定义工件以供其他项目使用的配置。

《依赖管理》
软件项目是各种功能的集合，它很少孤立地工作。在大多数情况下，项目取决于库的可重用性。同样，一个项目可以分为单独的组件以形成一个模块化的系统。依赖性管理
是一种以自动化方式声明，解决和使用项目所需依赖性的过程。下图演示了Gradle项目的结构。

Gradle Dependencies
Gradle为依赖关系管理提供了内置支持。在Gradle中，依赖项管理由两部分组成。它们如下:

 -Gradle必须了解构建或运行项目的项目要求。这些文件被称为项目的依赖项。
 -Gradle需要构建和上传项目所产生的数据。这些文件是项目的声明。
在Gradle中，大多数项目不是独立的。项目需要由其他项目构建的文件进行编译或测试等。例如，如果要在项目中使用Hibernate框架，则在编译时需要在类路径中使
用 hibernate jar文件。这些文件被称为项目的依赖项。在Gradle中，我们可以指定项目的依赖关系，Gradle着重于查找这些依赖关系并使之在项目中可用。我们
可以从远程Maven或Ivy存储库中下载这些依赖项，或者可以在项目中构建依赖项并将其包括在内。此过程称为依赖性解析(dependency resolution)。

依赖解决方案提供了优于Ant的优势。使用Ant，我们可以指定要加载的jar的绝对或相对路径。相对而言，在Gradle中，我们必须声明依赖项的名称来定义依赖项。另外，
当我们添加Apache Ivy时，Ant反映了类似的行为，因此在这种情况下Gradle更好。

项目本身的依赖关系表现为依赖关系。例如，在hibernate-core中，我们需要许多必须在类路径上可用的库。因此，当Gradle测试运行项目时，它会搜索依赖项并使
之可用。这些依赖性称为传递性依赖性(transitive dependencies)。
*/


Gradle构建脚本描述一个或多个项目。每个项目都由不同的任务组成。任务是构建执行的一项工作。任务可以是编译一些类，将类文件存储到单独的目标文件夹中，创建JAR，生成Javadoc或将一些归档发布到存储库。
《定义任务》
任务是用于将任务定义到构建脚本中的关键字。看看下面的例子，它是一个叫作 hello 的任务，将打印一个字符串：hello world。将以下脚本复制并保存到 build.gradle 文件中。 此构建脚本定
义一个名称为 “hello” 的任务，用于打印hello world字符串。
task hello {
   doLast {
      println 'hello world'
   }
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下： 

D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q hello
hello world

可以通过为 doLast 语句指定快捷方式（表示符号 <<）来简化此 hello 任务。如果添加这个快捷方式到上面的 hello 任务中，参考如下脚本。
task hello << {
   println 'hello world'
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下： 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q hello
hello world

《任务依赖关系》
您可能已经猜到，可以声明依赖于其他任务的任务。下面声明依赖于其他任务的任务，将以下代码复制并保存到build.gradle文件中。
task hello << {
    println 'Hello world!'
}
task intro(dependsOn: hello) << {
    println "I'm Gradle"
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下： 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q intro
Hello world!
I'm Gradle

要添加依赖关系，相应的任务不需要存在。懒依赖 - 其他任务不存在，将以下代码复制并保存到build.gradle文件中。
task taskX(dependsOn: 'taskY') << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下：
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q taskX
taskY
taskX

《定位任务》
如果要查找在构建文件中定义的任务，则必须使用相应的标准项目属性。这意味着每个任务都可以作为项目的属性，使用任务名称作为属性名称。看看下面的代码访问任务作为属性。将以下代码复制并保存
到build.gradle文件中。
task hello

println hello.name
println project.hello.name

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下： 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q hello
hello
hello

您还可以通过任务集合使用所有属性。将以下代码复制并保存到build.gradle文件中。
task hello

println tasks.hello.name
println tasks['hello'].name

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下： 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q hello
hello
hello

《向任务添加依赖关系》
要将一个任务依赖于另一个任务，这意味着当一个任务完成时，另一个任务将开始。 每个任务都使用任务名称进行区分。 任务名称集合由其任务集合引用。 要引用另一个项目中的任务，应该使
用项目路径作为相应任务名称的前缀。以下示例将从任务taskX添加依赖项到任务taskY。
task taskX << {
   println 'taskX'
}
task taskY(dependsOn: 'taskX') << {
   println "taskY"
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下：
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q taskY
taskX
taskY

上面的例子是通过使用名字添加对任务的依赖。 还有另一种方法实现任务依赖性，即使用Task对象定义依赖性。现在采用上面任务的相同示例，但是使用任务对象而不是任务参考名称来实现依懒关系。将以下代码
复制并保存到build.gradle文件中。
task taskY << {
   println 'taskY'
}
task taskX << {
   println 'taskX'
}
taskY.dependsOn taskX

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下 - 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q taskY
taskX
taskY

还有另一种方法来添加任务依赖，它就是通过使用闭包。在这种情况下，任务通过闭包释放如果您在构建脚本中使用闭包，那么应该返回任务对象的单个任务或集合。以下示例将任务中从taskX添加依赖项到项目中
的所有任务，其名称以“lib”开头。将以下代码复制并保存到build.gradle文件中。
task taskX << {
   println 'taskX'
}

taskX.dependsOn {
   tasks.findAll { 
     task -> task.name.startsWith('lib') 
   }
}
task lib1 << {
   println 'lib1'
}
task lib2 << {
   println 'lib2'
}
task notALib << {
   println 'notALib'
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下 - 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q taskX
lib1
lib2
taskX

《向任务添加描述》
可以向任务添加描述。 执行Gradle任务时会显示此描述。 这可以通过使用description关键字。将以下代码复制并保存到build.gradle文件中。
task copy(type: Copy) {
   description 'Copies the resource directory to the target directory.'
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
   println("description applied")
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下 - 
//D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q taskX？ 应为：
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q copy
description applied

《跳过任务》
如果用于跳过任务的逻辑不能用谓词表示，则可以使用StopExecutionException。 如果操作抛出此异常，则会跳过此操作的进一步执行以及此任务的任何后续操作的执行。 构建继续执行下一个任务。将以
下代码复制并保存到build.gradle文件中。
task compile << {
    println 'We are doing the compile.'
}

compile.doFirst {
    // Here you would put arbitrary conditions in real life.
    // But this is used in an integration test so we want defined behavior.
    if (true) { throw new StopExecutionException() }
}
task myTask(dependsOn: 'compile') << {
   println 'I am not affected'
}

在存储 build.gradle 文件的目录位置执行以下命令，应该看到输出结果如下 - 
D:/worksp/yiibai.com/gradle-3.1/study/script>gradle -q myTask
I am not affected

Gradle在处理任务时有不同的阶段。 首先，有一个配置阶段，其中直接在任务的闭包中指定的代码被执行。 针对每个可用任务执行配置块，而不仅针对稍后实际执行的那些任务


